﻿#ifndef DOMAINOBJECT_H
#define DOMAINOBJECT_H


#include <QString>
#include <QVector>
#include <QMap>
#include <QVariant>
#include <QColor>

#include "controlinfo.h"

/*
 * Domain Object Interface
 */
class DomainObject
{
public:
    explicit DomainObject(DomainObject* parent = 0);

public:
    virtual int getNumberOfDescendant() = 0;
    virtual QList<DomainObject*> getDescendant() = 0;
    virtual QList<QString> getDescription() = 0;
    virtual QList<QString> getCheckedDescription() = 0;

    virtual void setChecked() = 0;
    virtual void cleanChecked() = 0;
    virtual void invertChecked() = 0;
    virtual int countChecked() = 0;

    virtual void setName(const QString& name) = 0;
    virtual const QString& getName() = 0;

    virtual DomainObject* getParent() = 0;

public:
    // Control Interface
    virtual void setControlInfos(const QMap<int, ControlInfo>& controls);
    virtual const QMap<int, ControlInfo>& getControlInfos();

    virtual QList<int> getControlAddrs(int id) = 0;
    virtual QList<int> getControlValues(int id) = 0;
    virtual bool doControl(int id) = 0;
    virtual bool doControl(int id, double value) = 0;

protected:
    // name
    QString                 name;
    // parent
    DomainObject*           parent;
    // control
    QMap<int, ControlInfo>  controls;
};


// Base for Station and Line
class DomainObjectCollection : public DomainObject
{
public:
    explicit DomainObjectCollection(DomainObject* parent = 0);

public:
    virtual void addChild(DomainObject* domainObject);
    virtual int getNumberOfDescendant();
    virtual QList<DomainObject*> getDescendant();
    virtual QList<QString> getDescription();
    virtual QList<QString> getCheckedDescription();

    virtual void setChecked();
 //    virtual void setUNChecked();
    virtual void cleanChecked();
    virtual void invertChecked();
    virtual int countChecked();

    virtual void setName(const QString& name);
    virtual const QString& getName();

    virtual DomainObject* getParent();

    virtual QList<int> getControlAddrs(int id);
    virtual QList<int> getControlValues(int id);
    virtual bool doControl(int id);
    virtual bool doControl(int id, double value);

protected:
    QList<DomainObject*>    children;
};

// Station Domain Object
class DomainObjectStation : public DomainObjectCollection
{
public:
    explicit DomainObjectStation(DomainObject* parent = 0);
};

// Line Domain Object
class DomainObjectLine : public DomainObjectCollection
{
public:
    explicit DomainObjectLine(DomainObject* parent = 0);
};

// Turbine Domain Object
class DomainObjectTurbine : public DomainObject
{
public:
    explicit DomainObjectTurbine(DomainObject* parent = 0);

public:
    virtual int getNumberOfDescendant();
    virtual QList<DomainObject*> getDescendant();
    virtual QList<QString> getDescription();
    virtual QList<QString> getCheckedDescription();

public:
    // Add point addr and value
    virtual void setPointsAddr(const QMap<int, QString>& pointsAddr);
    virtual QVariant getPointValue(int id);

    // Get/Set Turbine Name;
    virtual void setName(const QString& name);
    virtual const QString& getName();

    virtual DomainObject* getParent();

    // Set/Get Transition
    virtual void setStatePointId(int id);
    virtual int getStatePointId();
    virtual void setTransition(const QMap<int, int>& transition);
    virtual void setDefaultState(int defaultstate);
    virtual QString getState();
    virtual QColor getStateColor();
    virtual QIcon getStateIcon();

    // Check State
    virtual void setChecked();
    virtual void cleanChecked();
    virtual void invertChecked();
    virtual int countChecked();

    virtual Qt::CheckState getCheckState();

    virtual QList<int> getControlAddrs(int id);
    virtual QList<int> getControlValues(int id);
    virtual bool doControl(int id);
    virtual bool doControl(int id, double value);

protected:
    // point and addr
    QMap<int, QString>      points;
    // state transition and default state
    int                     statePointId;
    QMap<int, int>          transition;
    int                     defaultState;
    // Check State
    Qt::CheckState          checkState;
};

#endif // DOMAINOBJECT_H
